#ifndef ODBC_DETAILS_BINDABLE_BUFFER_HPP
#define ODBC_DETAILS_BINDABLE_BUFFER_HPP

#include "odbc/details/bindable_buffer_base.hpp"
#include "odbc/types.hpp"
#include <boost/any.hpp>
#include <vector>

namespace odbc
{

namespace details
{

///	\ingroup OdbcAccess
/// \internal
/// \brief It provides the specialization of a bound buffer, for a fixed size data type.
///
/// \param T the C++ type that corresponds to this bound buffer type.
/// \param Tr the type traits class, providing the base utility types and functionality, specific to C++ - ODBC type 
///		association.
template< typename T, typename Tr = type_traits< T> >
class bindable_buffer
	: public bindable_buffer_base
{
protected:
	/// \brief It defines the type traits structure providing the basic types and operations for a specific 
	///		ODBC type - C++ type association.
	typedef typename Tr type_traits;

	/// \brief It defines the C++ value type associated with the buffer.
	typedef typename type_traits::value_type value_type;

	///	\brief It defines the buffer type to be used for gathering the data from the ODBC statements.
	typedef typename type_traits::buffer_type buffer_type;

	/// \brief It defines the type of the size values, used for dimensioning the bound buffer.
	typedef typename type_traits::size_type size_type;

public:
	/// \brief Initializes the buffer to be bound later. The bind position is set to an invalid value. Initially, 
	///		the buffer contains a null value.
	bindable_buffer()
		: buffer_( type_traits::create_buffer())
	{
	}

	/// \brief Initializes the buffer to be bound later. The bind position is set to an invalid value. Initially, the 
	///		buffer contains a null value.
	/// \param size this parameter is ignored, since this column buffer implementation refer to fixed-size field values.
	explicit bindable_buffer( size_type size)
		: buffer_( type_traits::create_buffer( (int)size))
	{
	}

	/// \brief It retrieves the address of the bound buffer. Since the buffer relates to a fixed size column, the buffer 
	///		containing the fetched value is also the bound buffer.
	/// \return the address of the buffer containing the fetched value. 
	virtual const void* buffer() const
	{
		return type_traits::buffer_to_void( buffer_);
	}

	/// \brief It returns the value contained in the buffer. If the buffer has \c NULL value, it returns an empty 
	///		\code boost::any \endcode object.
	virtual boost::any value() const
	{
		return this->is_null() 
			? boost::any() 
			: boost::any( type_traits::convert( buffer_));
	}

protected:
	/// \brief It is the bound buffer. The data will be fetched in this buffer.
	buffer_type buffer_;
};

} // namespace details
} // namespace odbc

#endif // ODBC_DETAILS_BINDABLE_BUFFER_HPP
